home *** CD-ROM | disk | FTP | other *** search
/ Hardcore Visual Basic 5.0 (2nd Edition) / Hardcore Visual Basic 5.0 - Second Edition (1997)(Microsoft Press).iso / Code / Random.bas < prev    next >
BASIC Source File  |  1997-06-14  |  5KB  |  137 lines

  1. Attribute VB_Name = "MRandom"
  2. Option Explicit
  3.  
  4. Public Enum EErrorRandom
  5.     eeBaseRandom = 13580    ' Random
  6. End Enum
  7.  
  8. ' For Random algorithm
  9. Private iLast As Long
  10. Private Const A As Long = 48271
  11. Private Const M As Long = 2147483647
  12. Private Const Q As Long = (M / A)
  13. Private Const R As Long = (M Mod A)
  14. Private Const rT As Single = 1# / M
  15.  
  16. Private Sub Class_Initialize()
  17.     iLast = Abs(timeGetTime)
  18. End Sub
  19.  
  20. ' Pedigree for the Random and Seed algorithms
  21.  
  22. '****************************************************************************
  23. '* PMMMLCG - Prime Modulus M Multiplicative Linear Congruential Generator   *
  24. '*  Modified version of the random number generator proposed by             *
  25. '*  Park & Miller in "Random Number Generators: Good Ones Are Hard to Find" *
  26. '*  CACM October 1988, Vol 31, No. 10                                       *
  27. '*   - Modifications proposed by Park to provide better statistical         *
  28. '*     properties (i.e. more "random" - less correlation between sets of    *
  29. '*     generated numbers                                                    *
  30. '*   - generator is of the form                                             *
  31. '*         x = ( x * A) % M                                                 *
  32. '*   - Choice of A & M can radically modify the properties of the generator *
  33. '*     the current values were chosen after followup work to the original   *
  34. '*     paper mentioned above.                                               *
  35. '*   - The generator has a period of 2^31 - 1 with numbers generated in the *
  36. '*     range of 0 < x < M                                                   *
  37. '*   - The generator can run on any machine with a 32-bit integer, without  *
  38. '*     overflow.                                                            *
  39. '*   - This generator is currently running on Sun 3/50, Sparc, IBM PC/XT,   *
  40. '*     IBM RS/6000 just to name a few...                                    *
  41. '****************************************************************************
  42. '*    John Burton                                                           *
  43. '*    G & A Technical Software, Inc                                         *
  44. '*    28 Research Drive                                                     *
  45. '*    Hampton, Va. 23666                                                    *
  46. '*                                                                          *
  47. '*    jcburt@cs.wm.edu                                                      *
  48. '*    jcburt@gatsibm.larc.nasa.gov                                          *
  49. '*    burton@asdsun.larc.nasa.gov                                           *
  50. '****************************************************************************
  51.  
  52. '*  Random() - return next random number
  53. '*
  54. '*      The Random() subroutine returns a pseudo-random long value in
  55. '*      the range Min <= x < Max
  56. Function Random(Optional ByVal iMin As Long = 0, _
  57.                 Optional ByVal iMax As Long = M) As Long
  58.     Dim iLo As Long, iHi As Long, iT As Long
  59. #If fComponent = 0 Then
  60.     If iLast = 0 Then Class_Initialize
  61. #End If
  62.     iHi = iLast / Q
  63.     iLo = iLast Mod Q
  64.   
  65.     iT = A * iLo - R * iHi
  66.     If iT > 0 Then
  67.         iLast = iT
  68.     Else
  69.         iLast = iT + M
  70.     End If
  71.     Random = iLast
  72.     If iMin <> 0 Or iMax <> M Then
  73.         If iMin < iMax Then
  74.             Random = iMin + (iLast Mod (iMax - iMin + 1))
  75.         Else
  76.             Random = iMax + (iLast Mod (iMin - iMax + 1))
  77.         End If
  78.     End If
  79.  
  80. End Function
  81.  
  82. '*  RandomReal() - return next random number
  83. '*
  84. '*      The RandomReal() function returns a pseudo-random floating point value
  85. '*      in the range 0.0 <= x < 1.0.
  86. Function RandomReal() As Single
  87.     RandomReal = CSng(Random * rT)
  88. End Function
  89.  
  90. '*  Seed - Set first random number in a sequence based on a seed
  91. '*
  92. '*      The Seed procedure sets the starting point for generating a series
  93. '*      of pseudo-random values. To re-initialize the generator with the same
  94. '*      sequennce, use -1 as the seed argument. Use any positive seed value sets the generator to a random
  95. '*      starting point.
  96. '*
  97. '*      Calling Random or RandomReal before any call to Seed will generate a
  98. '*      sequence based on the system timer.
  99.  
  100. Sub Seed(Optional ByVal iSeed As Long = -1)
  101.  
  102.     Static iLastSeed As Long
  103.     Select Case iSeed
  104.     Case -1
  105.         ' -1 reserved for reinitializing last sequence
  106.         If iLastSeed Then iLast = iLastSeed Else iLast = Abs(timeGetTime)
  107.     Case 0
  108.         ' Algorithm won't handle 0 seed, so use it to represent timer
  109.         iLast = Abs(timeGetTime)
  110.     Case Else
  111.         iLast = Abs(iSeed)
  112.     End Select
  113.     iLastSeed = iLast
  114.     
  115. End Sub
  116.  
  117. #If fComponent = 0 Then
  118. Private Sub ErrRaise(e As Long)
  119.     Dim sText As String, sSource As String
  120.     If e > 1000 Then
  121.         sSource = App.ExeName & ".Random"
  122.         Select Case e
  123.         Case eeBaseRandom
  124.             BugAssert True
  125.        ' Case ee...
  126.        '     Add additional errors
  127.         End Select
  128.         Err.Raise COMError(e), sSource, sText
  129.     Else
  130.         ' Raise standard Visual Basic error
  131.         sSource = App.ExeName & ".VBError"
  132.         Err.Raise e, sSource
  133.     End If
  134. End Sub
  135. #End If
  136.  
  137.